<?php

namespace service\proxy;

/**
 * http request tool
 */
class curl {

    /**
     * $error
     *
     * @var array
     */
    private static $error = [];

    /**
     * origin returns
     *
     * @var null
     */
    public static $origin_return = null;

    /**
     * curl time_out|could use set option
     *
     * @var integer
     */
    public static $time_out = 10;

    /**
     * $headers
     *
     * @var array
     */
    private static $headers = [
        "cache-control: no-cache",
        "Pragma: no-cache",
        "Accept: */*",
    ];

    /**
     * cURL Options
     *
     * @var array
     */
    public static $OPTIONS = [];

    /**
     * set_option
     *
     * @param mixed $key
     * @param mixed $val
     * @return void
     */
    public static function set_option($key,$val = null){
        if (is_array($key)) {
            self::$OPTIONS = array_merge(self::$OPTIONS, $key);
        }elseif(is_scalar($key) && $val !== null){
            self::$OPTIONS[$key] = $val;
        }
    }

    /**
     * get_error
     *
     * @return array
     */
    public static function get_error() {
        return self::$error;
    }

    /**
     *
     * @param string $type
     * @return void
     */
    public static function set_content_type($type = 'text') {
        $content_types = [
            'xml' => 'text/xml',
            'text_xml' => 'text/xml',
            'text_plain' => 'text/plain',
            'application_xml' => 'application/xml',
            'html' => 'text/html',
        ];
        $tpl = "content-type : %s";
        isset($content_types[$type]) AND array_unshift(self::$headers, sprintf($tpl, $content_types[$type]));
    }

    /**
     * curl_setopt_array
     *
     * @param  resource &$ch
     * @param  array $curl_options
     * @param  boolean $skip_error 设置错误时是否跳过
     * @return boolean
     */
    private static function curl_setopt_array(&$ch, array $curl_options, $skip_error = true) {
       foreach ($curl_options as $option => $value) {
           if (!curl_setopt($ch, $option, $value) && !$skip_error) {
               return false;
           }
       }
       return true;
    }

    /**
     * get
     *
     * @param  string $url
     * @param  array|string $data
     * @param  array  $options
     * @return mixed
     */
    public static function get($url,$data = null, array $options = []){
        return self::request($url, $data, 'get', $options);
    }

    /**
     * post
     *
     * @param  string $url
     * @param  array|string $data
     * @param  array  $options
     * @return mixed
     */
    public static function post($url,$data = null, array $options = []){
        return self::request($url, $data, 'post', $options);
    }

    /**
     * set_timeout
     *
     * @param integer $time
     * @return boolean
     */
    public static function set_timeout($time){
        return is_numeric($time) AND self::$time_out = (int)$time;
    }

    /**
     * set_request_header
     *
     * @param array|string $headers
     * @return boolean
     */
    public static function set_request_header($headers){
        if(is_array($headers)){
            self::$header = array_merge(self::$header, $headers);
        }elseif(is_string($headers)){
            self::$header[] = $headers;
        }
    }

    /**
     * get_request_header
     *
     * @return boolean|array
     */
    public static function get_request_header(){
        return is_array(self::$header)? array_unique(self::$header) : false;
    }

    /**
     * curl handler
     * @access public
     * @static true
     * @param string $url
     * @param string $method [request type:get post put etc]
     * @param array or string $data [post data]
     * @return mixed
     */
    public static function request($url,$data = null, $method = 'get', array $options = []) {
        if ($url === '') {
            return false;
        }
        $ch = curl_init();
        $curl_options = [
            CURLOPT_URL =>  $url,
            // CURLOPT_HTTPHEADER =>  self::get_request_header(),
            CURLOPT_CUSTOMREQUEST =>  strtoupper($method),
            CURLOPT_TIMEOUT =>  self::$time_out,
            CURLOPT_USERAGENT =>  'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML =>  like Gecko) Chrome/44.0.2403.125 Safari/537.36',
            CURLOPT_AUTOREFERER =>  true,
            CURLOPT_RETURNTRANSFER =>  true,
            CURLOPT_HEADER =>  false,
            CURLOPT_SSL_VERIFYPEER =>  false,
            CURLOPT_SSL_VERIFYHOST =>  false,
            CURLOPT_AUTOREFERER => true,
            CURLOPT_FOLLOWLOCATION =>  true,
        ];
        if ($data) {
            if (strtolower($method) === 'post') {
                $curl_options[CURLOPT_POSTFIELDS] = $data;
            } else {
                $url .= (stripos($url, '?') === false ? '?' : '&') . http_build_query($data);
                $curl_options[CURLOPT_URL] = $url;
            }
        }
        if(is_array(self::$OPTIONS) && count(self::$OPTIONS)){
            $curl_options = array_replace($curl_options, self::$OPTIONS);
        }
        is_array($options) AND count($options) AND $curl_options = array_replace($curl_options, $options);
        if(!curl_setopt_array($ch, $curl_options)){
            // if(function_exists('curl_reset')){
            //  curl_reset($ch);
            // }else{
            //  curl_close($ch);
            //  $ch = curl_init();
            // }
            //self::curl_setopt_array($ch, $curl_options);
        }
        $return = curl_exec($ch);
        if ($return === false) {
            self::$error['msg'] = curl_error($ch);
            self::$error['err_code'] = curl_errno($ch);
            self::$error['curl_info'] = curl_getinfo($ch);
            curl_close($ch);
            return false;
        }
        curl_close($ch);
        return $return;
    }
}
